# 免费大模型API集成模块
import os
import json
import time
import requests
import logging
from typing import Optional, Dict, List, Any

logger = logging.getLogger(__name__)

class FreeLLMAPIInterface:
    """免费大模型API接口封装"""
    
    def __init__(self, api_provider: str = "deepseek", api_key: str = None):
        """
        初始化免费大模型API接口
        
        Args:
            api_provider: API提供商，支持 "deepseek", "zhipuai", "qwen", "doubao", "xunfei"
            api_key: API密钥，如果为None则使用环境变量中的密钥
        """
        self.api_provider = api_provider.lower()
        self.api_key = api_key or self._get_api_key_from_env()
        self.timeout = 30  # 默认超时时间
        
        # 各API提供商的配置
        self.api_configs = {
            "deepseek": {
                "base_url": "https://api.deepseek.com/v1/chat/completions",
                "default_model": "deepseek-chat",
                "headers": lambda key: {
                    "Content-Type": "application/json",
                    "Authorization": f"Bearer {key}"
                }
            },
            "zhipuai": {
                "base_url": "https://open.bigmodel.cn/api/paas/v4/chat/completions",
                "default_model": "glm-4",
                "headers": lambda key: {
                    "Content-Type": "application/json",
                    "Authorization": f"Bearer {key}"
                }
            },
            "qwen": {
                "base_url": "https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation",
                "default_model": "qwen-plus",
                "headers": lambda key: {
                    "Content-Type": "application/json",
                    "Authorization": f"Bearer {key}"
                }
            },
            "doubao": {
                "base_url": "https://api.doubao.com/chat/completions",
                "default_model": "ERNIE-Bot",
                "headers": lambda key: {
                    "Content-Type": "application/json",
                    "Authorization": f"Bearer {key}"
                }
            },
            "xunfei": {
                "base_url": "https://spark-api.xf-yun.com/v3.5/chat/completions",
                "default_model": "spark-pro",
                "headers": lambda key: {
                    "Content-Type": "application/json",
                    "Authorization": f"Bearer {key}"
                }
            }
        }
        
        # 验证API提供商是否支持
        if self.api_provider not in self.api_configs:
            raise ValueError(f"不支持的API提供商: {self.api_provider}。支持的提供商: {list(self.api_configs.keys())}")
        
        logger.info(f"初始化免费大模型API接口: {self.api_provider}")
    
    def _get_api_key_from_env(self) -> Optional[str]:
        """从环境变量获取API密钥"""
        env_keys = {
            "deepseek": "DEEPSEEK_API_KEY",
            "zhipuai": "ZHIPUAI_API_KEY",
            "qwen": "QWEN_API_KEY",
            "doubao": "DOUBAO_API_KEY",
            "xunfei": "XUNFEI_API_KEY"
        }
        
        env_key = env_keys.get(self.api_provider)
        if env_key:
            return os.environ.get(env_key)
        return None
    
    def generate_response(self, prompt: str, conversations: List[Dict] = None, **kwargs) -> str:
        """
        生成大模型响应
        
        Args:
            prompt: 用户提示
            conversations: 对话历史
            **kwargs: 其他参数
            
        Returns:
            模型生成的响应文本
        """
        try:
            # 检查API密钥
            if not self.api_key:
                logger.warning(f"未配置{self.api_provider}的API密钥，将使用模拟响应")
                return self._generate_mock_response(prompt)
            
            # 构建请求
            config = self.api_configs[self.api_provider]
            model = kwargs.get("model", config["default_model"])
            temperature = kwargs.get("temperature", 0.7)
            max_tokens = kwargs.get("max_tokens", 1024)
            
            # 构建消息列表
            messages = []
            
            # 添加系统提示（如果有）
            system_prompt = kwargs.get("system_prompt")
            if system_prompt:
                messages.append({"role": "system", "content": system_prompt})
            
            # 添加历史对话
            if conversations:
                messages.extend(conversations)
            
            # 添加用户提示
            messages.append({"role": "user", "content": prompt})
            
            # 构建请求数据
            if self.api_provider == "qwen":
                # 文心一言API格式略有不同
                data = {
                    "model": model,
                    "input": {
                        "messages": messages
                    },
                    "parameters": {
                        "temperature": temperature,
                        "max_tokens": max_tokens
                    }
                }
            else:
                # 标准OpenAI兼容格式
                data = {
                    "model": model,
                    "messages": messages,
                    "temperature": temperature,
                    "max_tokens": max_tokens
                }
            
            # 发送请求
            headers = config["headers"](self.api_key)
            response = requests.post(
                config["base_url"],
                headers=headers,
                json=data,
                timeout=self.timeout
            )
            
            # 解析响应
            response_data = response.json()
            
            # 检查响应状态
            if response.status_code != 200:
                error_msg = response_data.get("error", {}).get("message", str(response_data))
                raise Exception(f"API请求失败: {response.status_code} - {error_msg}")
            
            # 提取生成内容
            if self.api_provider == "qwen":
                # 文心一言响应格式
                content = response_data.get("output", {}).get("choices", [{}])[0].get("message", {}).get("content", "")
            else:
                # 标准OpenAI兼容格式
                content = response_data.get("choices", [{}])[0].get("message", {}).get("content", "")
            
            if not content:
                raise Exception("未从API响应中获取内容")
            
            logger.info(f"成功获取{self.api_provider}模型响应")
            return content.strip()
            
        except Exception as e:
            logger.error(f"调用{self.api_provider}API时出错: {str(e)}")
            # 出错时返回模拟响应
            return self._generate_mock_response(prompt)
    
    def _generate_mock_response(self, prompt: str) -> str:
        """生成模拟响应，当API调用失败时使用"""
        # 基础模拟响应逻辑
        if '外卖' in prompt:
            return json.dumps({
                'task_type': 'food_delivery',
                'analyzed_request': prompt,
                'collected_info': {},
                'missing_info': ['restaurant', 'dishes', 'address'],
                'recommended_action': 'ask_user'
            }, ensure_ascii=False)
        elif '浏览器' in prompt or '网页' in prompt:
            return json.dumps({
                'task_type': 'complex_browser_task',
                'analyzed_request': prompt,
                'collected_info': {},
                'missing_info': ['website', 'target_actions'],
                'recommended_action': 'ask_user'
            }, ensure_ascii=False)
        elif '工作流' in prompt or '自动化' in prompt:
            return json.dumps({
                'task_type': 'workflow_automation',
                'analyzed_request': prompt,
                'collected_info': {},
                'missing_info': ['workflow_goal', 'available_resources'],
                'recommended_action': 'ask_user'
            }, ensure_ascii=False)
        elif '信息' in prompt and '提取' in prompt:
            return json.dumps({"extracted_info": "从用户回复中提取的信息"})
        elif '打开' in prompt and '应用' in prompt:
            app_name = prompt.replace('打开', '').replace('应用', '').strip()
            return json.dumps({"action": "open_app", "app_name": app_name})
        elif '关闭' in prompt and '应用' in prompt:
            app_name = prompt.replace('关闭', '').replace('应用', '').strip()
            return json.dumps({"action": "close_app", "app_name": app_name})
        else:
            return f"这是来自{self.api_provider}模型的模拟响应。我正在处理您的请求: {prompt[:50]}..."
    
    def validate_api_key(self) -> bool:
        """验证API密钥是否有效"""
        try:
            if not self.api_key:
                return False
            
            # 发送一个简单的请求来验证密钥
            test_prompt = "你好，请简单介绍自己"
            response = self.generate_response(test_prompt, max_tokens=50)
            return len(response) > 0
        except Exception:
            return False
    
    def list_available_models(self) -> List[str]:
        """列出可用的模型"""
        models = {
            "deepseek": ["deepseek-chat", "deepseek-coder"],
            "zhipuai": ["glm-4", "glm-4-flash", "glm-3-turbo"],
            "qwen": ["qwen-plus", "qwen-max", "qwen-turbo"],
            "doubao": ["ERNIE-Bot", "ERNIE-Bot-4"],
            "xunfei": ["spark-pro", "spark-lite"]
        }
        return models.get(self.api_provider, [])

class FreeLLMManager:
    """免费大模型管理器，用于管理多个API提供商"""
    
    def __init__(self):
        """初始化免费大模型管理器"""
        self.available_apis = {}
        self.default_api = None
        self.logger = logger
    
    def register_api(self, api_provider: str, api_key: str = None) -> bool:
        """
        注册一个API提供商
        
        Args:
            api_provider: API提供商名称
            api_key: API密钥
            
        Returns:
            是否注册成功
        """
        try:
            api_interface = FreeLLMAPIInterface(api_provider, api_key)
            
            # 验证API密钥
            if api_interface.validate_api_key():
                self.available_apis[api_provider] = api_interface
                self.logger.info(f"成功注册API提供商: {api_provider}")
                
                # 如果是第一个成功注册的API，设置为默认API
                if not self.default_api:
                    self.default_api = api_provider
                
                return True
            else:
                self.logger.warning(f"API密钥验证失败，未注册API提供商: {api_provider}")
                return False
        except Exception as e:
            self.logger.error(f"注册API提供商{api_provider}时出错: {str(e)}")
            return False
    
    def generate(self, prompt: str, api_provider: str = None, **kwargs) -> str:
        """
        生成响应
        
        Args:
            prompt: 用户提示
            api_provider: 指定的API提供商，不指定则使用默认API
            **kwargs: 其他参数
            
        Returns:
            生成的响应
        """
        # 确定使用的API提供商
        target_api = api_provider or self.default_api
        
        if not target_api or target_api not in self.available_apis:
            # 如果没有可用的API，尝试使用模拟模式
            self.logger.warning("没有可用的API提供商，使用模拟响应")
            mock_interface = FreeLLMAPIInterface("deepseek", None)
            return mock_interface._generate_mock_response(prompt)
        
        # 使用指定的API生成响应
        api_interface = self.available_apis[target_api]
        return api_interface.generate_response(prompt, **kwargs)
    
    def get_available_apis(self) -> List[str]:
        """获取所有可用的API提供商"""
        return list(self.available_apis.keys())
    
    def set_default_api(self, api_provider: str) -> bool:
        """
        设置默认API提供商
        
        Args:
            api_provider: API提供商名称
            
        Returns:
            是否设置成功
        """
        if api_provider in self.available_apis:
            self.default_api = api_provider
            self.logger.info(f"设置默认API提供商: {api_provider}")
            return True
        else:
            self.logger.warning(f"API提供商{api_provider}不可用，无法设置为默认")
            return False

# 工厂函数：创建免费大模型接口实例
def create_free_llm_interface(api_provider: str = "deepseek", api_key: str = None) -> FreeLLMAPIInterface:
    """
    创建免费大模型接口实例
    
    Args:
        api_provider: API提供商
        api_key: API密钥
        
    Returns:
        FreeLLMAPIInterface实例
    """
    return FreeLLMAPIInterface(api_provider, api_key)

# 工厂函数：创建免费大模型管理器
def create_free_llm_manager() -> FreeLLMManager:
    """
    创建免费大模型管理器实例
    
    Returns:
        FreeLLMManager实例
    """
    manager = FreeLLMManager()
    
    # 尝试自动注册所有支持的API提供商（从环境变量获取密钥）
    for provider in ["deepseek", "zhipuai", "qwen", "doubao", "xunfei"]:
        manager.register_api(provider)
    
    return manager